const fs = require('fs');
const path = require('path');
const babelParser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const babel = require('@babel/core');

// 分析单个模块
function analyzeModule(filePath) {
    const content = fs.readFileSync(filePath, 'utf-8');
    const ast = babelParser.parse(content, { sourceType: 'module' });

    const dependencies = [];
    traverse(ast, {
        ImportDeclaration({ node }) {
            dependencies.push(node.source.value);
        },
    });

    const { code } = babel.transformFromAstSync(ast, content, {
        presets: ['@babel/preset-env'],
    });

    return { filePath, dependencies, code };
}

// 构建依赖图
function createDependencyGraph(entry) {
    const entryModule = analyzeModule(entry);
    const graph = [entryModule];

    for (const module of graph) {
        const dirname = path.dirname(module.filePath);
        module.mapping = {};

        module.dependencies.forEach((relativePath) => {
            const absolutePath = path.join(dirname, relativePath);
            const childModule = analyzeModule(absolutePath);
            module.mapping[relativePath] = absolutePath;
            graph.push(childModule);
        });
    }

    return graph;
}

// 生成打包后的代码
function bundle(graph) {
    let modules = '';

    graph.forEach((mod) => {
        modules += `
            "${mod.filePath}": [
                function(require, module, exports) { ${mod.code} },
                ${JSON.stringify(mod.mapping)},
            ],
        `;
    });

    return `
        (function(modules) {
            function require(filePath) {
                const [fn, mapping] = modules[filePath];
                function localRequire(relativePath) {
                    return require(mapping[relativePath]);
                }
                const module = { exports: {} };
                fn(localRequire, module, module.exports);
                return module.exports;
            }
            require("${graph[0].filePath}");
        })({${modules}})
    `;
}

// 使用
const entry = './src/index.js'; // 入口文件
const graph = createDependencyGraph(entry);
const result = bundle(graph);

// 输出打包结果
fs.writeFileSync('./dist/bundle.js', result);